/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.network.chassis.ems;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import twaver.Element;
import twaver.EnumType;
import twaver.EnumTypeManager;
import twaver.Generator;
import twaver.Grid;
import twaver.MovableFilter;
import twaver.ResizableFilter;
import twaver.TDataBox;
import twaver.TUIManager;
import twaver.TWaverConst;
import twaver.TWaverUtil;
import twaver.network.TNetwork;
import twaver.network.background.ColorBackground;
import twaver.swing.TableLayout;
import demo.DemoPane;

public class EMSDemo extends DemoPane {

	private TDataBox box = new TDataBox();
	private TNetwork network = new TNetwork(box);
	private Grid rack = new Grid();
	private List percentList = new ArrayList();
	private int percentGridGradient = TWaverConst.GRADIENT_EXTEND_W;
	private boolean isResizable = true;
	private boolean isMovable = true;
	private Timer timer = new Timer(100, new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			if(!network.getCanvas().isShowing()){
				return;
			}
			int size = percentList.size();
			for (int i = 0; i < size; i++) {
				Element element = (Element) percentList.get(i);
				double percent = ((Double) (element.getClientProperty(EMSGridUI.PERCENT))).doubleValue();
				boolean isUp = ((Boolean) element.getClientProperty("gridup")).booleanValue();
				double step = 0.02;
				if ((percent + step) > 1) {
					isUp = false;
					percent = 1;
				}
				if ((percent - step) < 0) {
					isUp = true;
					percent = 0;
				}
				element.putClientProperty("gridup", isUp);
				if (isUp) {
					element.putClientProperty(EMSGridUI.PERCENT, new Double(percent + step));
				} else {
					element.putClientProperty(EMSGridUI.PERCENT, new Double(percent - step));
				}
			}
		}
	});

	public EMSDemo() {
		initGUI();
		initBox();
		initNetwork();
		timer.start();
	}

	private void initGUI() {
		this.setLayout(new BorderLayout());
		this.add(network, BorderLayout.CENTER);
	}

	private void initBox() {
		rack.setRowCount(12);
		rack.putBorderStroke(TWaverConst.STROKE_SQUARE_THIN);
		rack.setColumnCount(24);
		rack.setLocation(50, 50);
		rack.setSize(600, 500);
		rack.setBorder(new Insets(10, 10, 10, 10));
		rack.setPadding(new Insets(1, 1, 1, 1));
		rack.putRenderColor(Color.GREEN.darker());
		box.addElement(rack);

		for (int i = 0; i < 2; i++) {
			Grid systemGrid = getSystemGrid(i);
			systemGrid.setHost(rack);
			box.addElement(systemGrid);
		}
		for (int i = 0; i < 4; i++) {
			Grid moduleGrid = getModuleGrid(i);
			moduleGrid.setHost(rack);
			box.addElement(moduleGrid);
		}
		for (int j = 0; j < 4; j++) {
			for (int i = 0; i < 6; i++) {
				Grid grid = getCellGrid(j * 6 + i);
				grid.setHost(rack);
				box.addElement(grid);
				grid = getPercentGrid(j * 6 + i);
				percentList.add(grid);
				grid.putClientProperty(EMSGridUI.PERCENT, new Double((j * 6 + i) / 24.0));
				grid.putClientProperty("gridup", Boolean.TRUE);
				grid.setHost(rack);
				box.addElement(grid);
			}
		}
	}

	private void initNetwork() {
		network.setMovableFilter(new MovableFilter() {
			public boolean isMovable(Element element) {
				return isMovable;
			}
		});
		network.setResizableFilter(new ResizableFilter() {
			public boolean isResizable(Element element) {
				return isResizable;
			}
		});
		network.setElementSelectColorGenerator(new Generator() {
			public Object generate(Object object) {
				return Color.WHITE;
			}
		});
		network.setEnableDeleteWithKeyboard(true);
		network.setBackground(new ColorBackground(Color.DARK_GRAY));

		JPanel controlPanel = getControlPanel();
		controlPanel.setBackground(new Color(200,200,200,200));
		network.addComponentOnCanvas(controlPanel, GridBagConstraints.NORTHEAST);
	}

	private JPanel getControlPanel() {
		JPanel controlPanel = TWaverUtil.createVerticalPanel(2);
		controlPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

		JPanel checkPanel = new JPanel(new GridLayout(2, 2));
		final JCheckBox resizeCheckBox = new JCheckBox("Resizable");
		resizeCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				isResizable = resizeCheckBox.isSelected();
				network.updateTViewUI();
			}
		});
		resizeCheckBox.setSelected(true);
		checkPanel.add(resizeCheckBox);

		final JCheckBox moveCheckBox = new JCheckBox("Movable");
		moveCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				isMovable = moveCheckBox.isSelected();
			}
		});
		moveCheckBox.setSelected(true);
		checkPanel.add(moveCheckBox);
		
		final JCheckBox showCellCheckBox = new JCheckBox("Cell Visible");
		showCellCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rack.setPaintCell(showCellCheckBox.isSelected());
			}
		});
		showCellCheckBox.setSelected(true);
		checkPanel.add(showCellCheckBox);

		final JCheckBox deleteCheckBox = new JCheckBox("Delete With Keyboard");
		deleteCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				network.setEnableDeleteWithKeyboard(deleteCheckBox.isSelected());
			}
		});
		deleteCheckBox.setSelected(true);
		checkPanel.add(deleteCheckBox);
		controlPanel.add(checkPanel);

		double[] rows = new double[] { TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED };
		double[] cols = new double[] { TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED };
		JPanel panel = new JPanel(new TableLayout(cols, rows, 5, 2));
		int rowIndex = 0;

		panel.add(new JLabel("Percent Gradient"), "0," + rowIndex + ",0," + rowIndex);
		final JComboBox paintBox = TWaverUtil.createEnumComboBox(TWaverConst.ENUM_GRADIENT, false, "left");
		paintBox.setSelectedItem(EnumTypeManager.getInstance().getEnumType(TWaverConst.ENUM_GRADIENT, new Integer(percentGridGradient)));
		paintBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				EnumType enumType = (EnumType) paintBox.getSelectedItem();
				int size = percentList.size();
				for (int i = 0; i < size; i++) {
					Element element = (Element) percentList.get(i);
					element.putClientProperty(EMSGridUI.GRADIENTTYPE, enumType.getValue());
				}
			}
		});
		paintBox.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 6));
		panel.add(paintBox, "1," + rowIndex + ",1," + rowIndex);
		rowIndex++;

		panel.add(new JLabel("Rack Padding"), "0," + rowIndex + ",0," + rowIndex);
		final JTextField padText = new JTextField(3);
		panel.add(padText, "2," + rowIndex + ",2," + rowIndex);
		padText.setEditable(false);
		final JSlider padSlider = new JSlider(0, 10);
		padSlider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				int value = padSlider.getValue();
				rack.setPadding(new Insets(value, value, value, value));
				padText.setText(value + "");
			}
		});
		padSlider.setValue(rack.getPadding().top);
		padSlider.setPreferredSize(new Dimension(100, 20));
		padText.setText(rack.getPadding().top + "");
		panel.add(padSlider, "1," + rowIndex + ",1," + rowIndex);
		rowIndex++;

		panel.add(new JLabel("Border"), "0," + rowIndex + ",0," + rowIndex);
		final JTextField borderText = new JTextField(3);
		panel.add(borderText, "2," + rowIndex + ",2," + rowIndex);
		borderText.setEditable(false);
		final JSlider borderSlider = new JSlider(0, 20);
		borderSlider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				int value = borderSlider.getValue();
				rack.setBorder(new Insets(value, value, value, value));
				borderText.setText(value + "");
			}
		});
		borderSlider.setValue(rack.getBorder().top);
		borderSlider.setPreferredSize(new Dimension(100, 20));
		borderText.setText(rack.getBorder().top + "");
		panel.add(borderSlider, "1," + rowIndex + ",1," + rowIndex);
		rowIndex++;

		panel.add(new JLabel("Timer Delay"), "0," + rowIndex + ",0," + rowIndex);
		final JTextField timerText = new JTextField(3);
		panel.add(timerText, "2," + rowIndex + ",2," + rowIndex);
		timerText.setEditable(false);
		final JSlider timerSlider = new JSlider(100, 500);
		timerSlider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				int value = timerSlider.getValue();
				timer.setDelay(value);
				timerText.setText(value + "");
			}
		});
		timerSlider.setValue(100);
		timerSlider.setPreferredSize(new Dimension(100, 20));
		timerText.setText("100");
		panel.add(timerSlider, "1," + rowIndex + ",1," + rowIndex);

		controlPanel.add(panel);
		return controlPanel;
	}

	private Grid getPercentGrid(int column) {
		Grid grid = new Grid() {
			public String getUIClassID() {
				return EMSGridUI.class.getName();
			}

			public String getSVGUIClassID() {
				return EMSSVGGridUI.class.getName();
			}
		};
		grid.putBorderStroke(TWaverConst.STROKE_SQUARE_THIN);
		grid.putClientProperty(EMSGridUI.GRADIENTTYPE, percentGridGradient);
		grid.setRowSpan(8);
		grid.setColumnIndex(column);
		grid.setRowIndex(2);
		grid.setColumnSpan(1);
		return grid;
	}

	private Grid getModuleGrid(int column) {
		Grid grid = new Grid();
		setGridAttribute(grid);
		grid.putLabelColor(Color.WHITE);
		grid.putLabelFont(TUIManager.getDefaultPlainFont());
		grid.setName("Module" + (column + 1));
		grid.setColumnIndex(column * 6);
		grid.setRowIndex(0);
		grid.setColumnSpan(6);
		grid.putCustomDraw(true);
		grid.putCustomDrawShapeFactory(TWaverConst.SHAPE_RECTANGLE);
		grid.putCustomDrawGradientFactory(TWaverConst.GRADIENT_LINE_N);
		grid.putCustomDrawFillColor(Color.RED.darker());
		return grid;
	}

	private Grid getCellGrid(int column) {
		Grid grid = new Grid();
		setGridAttribute(grid);
		grid.putLabelColor(Color.WHITE);
		grid.putLabelFont(TUIManager.getDefaultPlainFont());
		grid.setName("" + (column + 1));
		grid.setColumnIndex(column);
		grid.setRowIndex(1);
		grid.setColumnSpan(1);
		grid.putCustomDraw(true);
		grid.putCustomDrawOutline(false);
		grid.putCustomDrawShapeFactory(TWaverConst.SHAPE_ROUND);
		grid.putCustomDrawGradientFactory(TWaverConst.GRADIENT_LINE_NE);
		grid.putCustomDrawFillColor(new Color(100, 0, 100, 200));
		return grid;
	}

	private Grid getSystemGrid(int column) {
		Grid grid = new Grid();
		setGridAttribute(grid);
		grid.putLabelColor(Color.DARK_GRAY);
		grid.setName("System" + (column + 1));
		grid.setColumnIndex(column * 12);
		grid.setRowIndex(10);
		grid.setRowSpan(2);
		grid.setColumnSpan(12);
		grid.putCustomDraw(true);
		grid.putCustomDrawShapeFactory(TWaverConst.SHAPE_RECTANGLE);
		grid.putCustomDrawGradientFactory(TWaverConst.GRADIENT_EXTEND_N);
		grid.putCustomDrawFillColor(new Color(0, 50, 100));
		return grid;
	}

	private void setGridAttribute(Grid grid) {
		grid.putBorderStroke(TWaverConst.STROKE_SQUARE_THIN);
		grid.putLabelHighlightable(false);
		grid.putLabelPosition(TWaverConst.POSITION_CENTER);
	}
}